package at.technikum.fotoalbum.utils;

import java.awt.Container;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/* works only for jpg now, png is still missing */

public class Thumbnail {

	private static final Log log = LogFactory.getLog(Thumbnail.class);

	private final static Thumbnail m_INSTANCE = new Thumbnail();

	private static int m_HEIGHT = 120; // How much height u want .. for new
	// Image

	private static int m_WIDTH = 100; // How much width u want .. for new
	// Image

	private static int m_QUALITY = 100; // How much Quality u want .. for new
	// Image

	private static String m_INPUT_IMAGE_PATH = "";

	private static String m_OUTPUT_IMAGE_PATH = ""; // For context related..
	// i.e. Relative

	private final static String m_MAIN_IMAGE_PATH = "/resources/pictures";

	private BufferedOutputStream out;

	Thumbnail() {
	}

	/**
	 * Constructor for Single output Image
	 * 
	 * @param String
	 *            as InputPath
	 * @param String
	 *            as OutputPath
	 * 
	 * @param int as Height
	 * @param int as Width
	 * @param int as Quality of picture
	 */
	public Thumbnail(String p_inputpath, String p_outputpath, int p_height,
			int p_width, int p_quality) {

		this.m_INPUT_IMAGE_PATH = p_inputpath;
		this.m_OUTPUT_IMAGE_PATH = p_outputpath;
		this.m_HEIGHT = p_height;
		this.m_WIDTH = p_width;
		this.m_QUALITY = p_quality;
	}

	/**
	 * Get the Instance of Class
	 */
	public static Thumbnail getInstance() {
		return m_INSTANCE;
	}

	/***************************************************************************
	 * Getter Setter Method
	 **************************************************************************/

	/*
	 * Get Height of Image @return int Height
	 */

	public int getHeight() {
		return this.m_HEIGHT;
	}

	/*
	 * Set Height of Image @param int Height
	 */
	public void setHeight(int p_height) {
		this.m_HEIGHT = p_height;
	}

	/*
	 * Get Width of Image @return int Width
	 */

	public int getWidth() {
		return this.m_WIDTH;
	}

	/*
	 * Set Width of Image @param int Width
	 */
	public void setWidth(int p_width) {
		this.m_WIDTH = p_width;
	}

	/*
	 * Get Quality of Image @return int Quality
	 */

	public int getQuality() {
		return this.m_QUALITY;
	}

	/*
	 * Set Quality of Image @param int Quality
	 */
	public void setQuality(int p_quality) {
		this.m_QUALITY = p_quality;
	}

	/*
	 * Get Input Path of Image @return String Input Path
	 */
	public String getMainImagePath() {
		return this.m_MAIN_IMAGE_PATH;
	}

	/*
	 * Get Input Path of Image @return String Input Path
	 */
	public String getInputPath() {
		return this.m_INPUT_IMAGE_PATH;
	}

	/*
	 * Set Input Path of Image @param String Input Path
	 */
	public void setInputPath(String p_inputpath) {
		this.m_INPUT_IMAGE_PATH = p_inputpath;
	}

	/*
	 * Get OutPut Path 1 of Image @return String Output Path
	 */
	public String getOutputPath() {
		return this.m_OUTPUT_IMAGE_PATH;
	}

	/*
	 * Set Output Path of Image @param String Output Path
	 */
	public void setOutputPath(String p_outputpath) {
		this.m_OUTPUT_IMAGE_PATH = p_outputpath;
	}
	
	public void generateThumImage() {
		commonGeneration();
	}
	
	private void commonGeneration() {
		try {
			Image image = Toolkit.getDefaultToolkit().getImage(getInputPath());
			MediaTracker mediaTracker = new MediaTracker(new Container());
			mediaTracker.addImage(image, 0);
			mediaTracker.waitForID(0);
			// determine thumbnail size from WIDTH and HEIGHT
			int thumbWidth = getWidth();
			int thumbHeight = getHeight();
			double thumbRatio = (double) thumbWidth / (double) thumbHeight;
			int imageWidth = image.getWidth(null);
			int imageHeight = image.getHeight(null);
			double imageRatio = (double) imageWidth / (double) imageHeight;
			if (thumbRatio < imageRatio) {
				thumbHeight = (int) (thumbWidth / imageRatio);
			} else {
				thumbWidth = (int) (thumbHeight * imageRatio);
			}
			// draw original image to thumbnail image object and
			// scale it to the new size on-the-fly
			BufferedImage thumbImage = new BufferedImage(thumbWidth,
					thumbHeight, BufferedImage.TYPE_INT_RGB);
			Graphics2D graphics2D = thumbImage.createGraphics();
			graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
					RenderingHints.VALUE_INTERPOLATION_BILINEAR);
			graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null);
			// save thumbnail image to OUTFILE
			out = new BufferedOutputStream(
					new FileOutputStream(getOutputPath()));
			/* Also set Main Image Path */
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			JPEGEncodeParam param = encoder
					.getDefaultJPEGEncodeParam(thumbImage);
			int quality = getQuality();
			quality = Math.max(0, Math.min(quality, 100));
			param.setQuality((float) quality / 100.0f, false);
			encoder.setJPEGEncodeParam(param);
			encoder.encode(thumbImage);
			out.close();
			log.info("Thumbnail: Builded thumbnail succesfully.");
		} catch (Exception e) {
			log.error("Thumbnail: Building thumbnail failed" + e.toString());
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException ioe) {
					log.error("Thumbnail: Cant close BufferdOutputStream.");
				}
			}
		}
	}
}
